<?php

namespace plugin\admin\app\controller;

use app\service\modbus\ModbusTcpService;
use plugin\admin\app\model\IotDevice;
use support\Request;
use support\Response;
use plugin\admin\app\model\IotDeviceChild;
use plugin\admin\app\controller\Crud;
use support\exception\BusinessException;
use support\View;

/**
 * 子设备
 */
class IotDeviceChildController extends Crud
{

    /**
     * @var IotDeviceChild
     */
    protected $model = null;

    protected $device_id=null;
    /**
     * 构造函数
     * @return void
     */
    public function __construct()
    {
        $this->model = new IotDeviceChild;
        parent::__construct();
    }

    /**
     * 浏览
     * @return Response
     */
    public function index(): Response
    {
        $device_id = request()->get('id',1);
        View::assign('device_id',$device_id);
        return view('iot-device-child/index');
    }

    /**
     * 插入
     * @param Request $request
     * @return Response
     * @throws BusinessException
     */
    public function insert(Request $request): Response
    {
        if ($request->method() === 'POST') {
            $device_id = request()->post('device_id','');
            if (empty($device_id)){
                return errorMessage("参数错误【device_id】未上传");
            }
            $name = $request->post('name');
            $uid = $request->post('uid');
            $iot_device_child = IotDeviceChild::where(['device_id'=>$device_id,'name'=>$name,'uid'=>$uid])->exists();
            if ($iot_device_child){
                return errorMessage("子设备地址和名称已存在");
            }
            return parent::insert($request);
        }
        $device_id = request()->get('device_id',1);
        View::assign('device_id',$device_id);
        return view('iot-device-child/insert');
    }

    /**
     * 更新
     * @param Request $request
     * @return Response
     * @throws BusinessException
    */
    public function update(Request $request): Response
    {
        if ($request->method() === 'POST') {
            $id = $request->post('id','');
            if (empty($id)){
                return errorMessage("参数错误【id】未上传");
            }
            $device_id = IotDeviceChild::where('id',$id)->value('device_id');
            $name = $request->post('name');
            $uid = $request->post('uid');
            $iot_device_child = IotDeviceChild::where(['device_id'=>$device_id,'name'=>$name,'uid'=>$uid])->where('id','<>',$id)->exists();
            if ($iot_device_child){
                return errorMessage("子设备地址和名称已存在");
            }
            return parent::update($request);
        }
        return view('iot-device-child/update');
    }

    /**
     * 调试
     * @param Request $request
     * @return Response
     */
    public function debugging(Request $request): Response
    {
        $device_id = $request->get('device_id','');
        if (empty($device_id)){
            return errorMessage("参数有误");
        }
        $child_id = $request->get('id','');
        if (empty($child_id)){
            return errorMessage("参数有误");
        }
        $child_name = IotDeviceChild::where('id',$child_id)->value('name');
        if(empty($child_name)){
            return errorMessage("子设备不存在");
        }
        $device_data = IotDevice::where('id',$device_id)->whereNotNull('ip')->whereNotNull('port')->first();
        if (empty($device_data)){
            return errorMessage("设备不存在");
        }
        if ($request->method()=="POST"){
            $data = $request->post();
            $ip = $device_data->ip;
            $port = $device_data->port;
            $type_name = $device_data->type_name;
            if ($type_name=="modbus"){
                $field_type = $data['field_type'];
                $modbus = new ModbusTcpService($ip,$port);
                $address = $data['address'];
                $address_value = $data['address_value'];
                $execution_method = $data['execution_method']??0;
                $field_bit_address = $data['field_bit_address'];
                $field_type_name = "string";
                if($field_type==0){
                    $field_type_name="bit";
                }elseif ($field_type==1){
                    $field_type_name="int16";
                }elseif ($field_type==2){
                    $field_type_name="uint16";
                }elseif ($field_type==3){
                    $field_type_name="int32";
                }elseif ($field_type==4){
                    $field_type_name="uint32";
                }elseif ($field_type==5){
                    $field_type_name="uint64";
                }elseif ($field_type==6){
                    $field_type_name="float";
                }elseif ($field_type==8){
                    $field_type_name="double";
                }elseif ($field_type==9){
                    $field_type_name="bit";
                }elseif ($field_type==10){
                    $field_type_name="byte";
                }elseif ($field_type==11){
                    $field_type_name="int64";
                }
                //读取类型: 0.是读取 1.写入
                if ($execution_method==0){
                    if ($field_type_name=="bit" && $field_bit_address>=0){
                        //bit数据处理
                        $arr=[
                            ['start_address'=>$address,'get_type'=>'bit','bit'=>$field_bit_address,'name'=>$address],
                        ];
                    }else{
                        $arr=[
                            ['start_address'=>$address,'get_type'=>$field_type_name,'name'=>$address],
                        ];
                    }
                    $get_data = $modbus->getModbusTcpTypeRead($arr);
                }else{
                    if ($field_type_name=="bit" && $field_bit_address>=0){
                        if ($address_value ==""){
                            return errorMessage("bit值必须填写");
                        }
                        if (!in_array($address_value,[0,1])){
                            return errorMessage("bit数字超出范围");
                        }
                        $arr_data=[['start_address'=>$address,'get_type'=>'uint16','name'=>$address]];
                        $get_data = $modbus->getModbusTcpTypeRead($arr_data);
                        if (is_array($get_data)){
                            $value = $get_data[0];
                            $string = decbin($value);
                            //目标的点位是在高位还是低位
                            if ($field_bit_address>=8){
                                //高位
                                $new_string = substr_replace($string,$address_value,($field_bit_address-8),1);
                            }else{
                                //低位
                                $new_string = substr_replace($string,$address_value,($field_bit_address+8),1);
                            }
                            //当前bit位的值与获取的值进行比对是否重复
                            if ($string==$new_string){
                                return errorMessage("勿重复操作");
                            }
                            $arr_write=[
                                ['start_address'=>$address,'get_type'=>'uint16','value'=>bindec($new_string)],
                            ];
                           $get_data = $modbus->getModbusTcpTypeWrite($arr_write);
                        }
                    }else{
                        $arr=[
                            ['start_address'=>$address,'get_type'=>$field_type_name,'value'=>$address_value],
                        ];
                        $get_data=$modbus->getModbusTcpTypeWrite($arr);
                    }
                }
                return successMessage("操作失败",[$get_data]);
            }

        }
        return view('iot-device-child/debugging',['device_id'=>$device_id,'child_id'=>$child_id]);
    }
}
